// 修改这一行
import axios, { type AxiosInstance, AxiosError, type AxiosRequestConfig, type AxiosResponse } from 'axios'



class Request {
  // 限制创建的实例必须是axios的实例
  private instance: AxiosInstance
  // 这个config是不能乱写的，axios对创建的配置有限制的
  constructor(config: AxiosRequestConfig) {
    this.instance = axios.create(config)
    // 接下来配置axios实例身上的全局配置，比如拦截器
    this.instance.interceptors.request.use(
      async (config: any) => {
        /**
         * 用户登录之后获取服务端返回的token,后面每次请求都在请求头中带上token进行JWT校验
         * token 存储在本地储存中（storage）、vuex、pinia
         */
        config.withCredentials = true
        const token = localStorage.getItem('token')
        // 自定义请求头
        if (token) {
          // 让每个请求携带token
          config.headers['Authorization'] = 'Bearer ' + token
        }
        return config
      },
      (error: AxiosError) => {
        return Promise.reject(error)
      },
    )
    this.instance.interceptors.response.use(
      (response: AxiosResponse) => response.data,
      async (error: AxiosError & { config: any }) => {
        const { response, config } = error
        // 401未授权：access_token 失效
        const data: any = error.response?.data
        if (data && data.error && data.error.details) {
          showErrMessage({ msg: data.error.details.errors })
        } else if (data && data.error && data.error.message) {
          showErrMessage({ msg: data.error.message })
        } else {
          // const errMsg: string = errorCodeType(error.response.status)
          // errMsg && showErrMessage({ msg: errMsg })
        }

        return Promise.reject(error)
      },
    )
  }
  // 公共方法，因为不知道返回值的类型
  fetchData<T>(options: AxiosRequestConfig): Promise<T> {
    // 将私有的instance上面发请求的操作，封装到这个实例方法request中，这个方法的返回值应该是一个promise对象
    return new Promise((resolve, reject) => {
      this.instance
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        .request<any, T>(options)
        .then((res) => {
          resolve(res)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }
  // 调用上面封装的实例方法request，来实现get / post / delete / put 方法的快捷调用
  get<T>(options: AxiosRequestConfig): Promise<T> {
    return this.fetchData<T>({ ...options, method: 'GET' })
  }
  post<T>(options: AxiosRequestConfig): Promise<T> {
    return this.fetchData({ ...options, method: 'POST' })
  }
  put<T>(options: AxiosRequestConfig): Promise<T> {
    return this.fetchData({ ...options, method: 'PUT' })
  }
  delete<T>(options: AxiosRequestConfig): Promise<T> {
    return this.fetchData({ ...options, method: 'DELETE' })
  }
}

/**
 * @description 显示错误消息
 * opt 传入参数
 * err 错误信息
 * type 消息类型
 * duration 消息持续时间
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function showErrMessage(err, type: any = 'error', duration = 5000) {
  alert(err.msg)

}

export const createService = (baseURL: string = import.meta.env.VITE_API_BASE_AUTH_URL) => {
  return new Request({
    // 默认请求地址，根据环境的不同可在.env 文件中进行修改
    baseURL: baseURL,
    // 设置接口访问超时时间
    timeout: 3000000, // request timeout，
    // 跨域时候允许携带凭证
    withCredentials: true,
  })
}

// 创建axios实例 进行基本参数配置
const appservice = createService()

export default appservice
